/*
 * Copyright 2014 Jonathan Haas
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package app.grinreader.render;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import app.grinreader.R;
import app.grinreader.model.*;

import java.util.*;

/**
 *
 */
public class BookView extends View {

	private BookModel bookModel;

	private ArrayDeque<BookPage> pages = new ArrayDeque<>();

	private TextPaint textPaint;
	private final float density;
	private final DisplayMetrics dm;

	public BookView(Context context, AttributeSet attrs) {
		super(context, attrs);

		dm = getResources().getDisplayMetrics();
		density = dm.density;

		textPaint = new TextPaint();
		textPaint.density = density;
		textPaint.setTypeface(Typeface.SERIF);
		textPaint.setAntiAlias(true);
		textPaint.setHinting(Paint.HINTING_ON);
		textPaint.setFlags(Paint.ANTI_ALIAS_FLAG); //  | Paint.LINEAR_TEXT_FLAG | Paint.SUBPIXEL_TEXT_FLAG
		TypedArray a = context.getTheme().obtainStyledAttributes(
				attrs,
				R.styleable.BookView,
				0, 0);

		try {
			textPaint.setTextSize(a.getDimension(R.styleable.BookView_textSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10f, dm)));
		} finally {
			a.recycle();
		}

	}

	private void setTextSize(float textSize) {
		textPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, textSize, dm));
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		if(bookModel == null) return;
		super.onSizeChanged(w, h, oldw, oldh);
		BookPosition tmp = getStartPosition();
		createPages(w, h);
		setStartPosition(tmp);
		invalidate();
	}

	private void createPages(int w, int h) {
		pages.clear();
		float width = w * density;
		float height = h * density;
		float topPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8f, dm);
		float pixelPadding= textPaint.getTextSize()*.75f + topPadding;
		if(width > height && w > 50.0f * textPaint.getTextSize()){
			pages.add(new BookPage(bookModel, new RectF(pixelPadding, topPadding, (w-pixelPadding) / 2, (h-topPadding)), textPaint));
			pages.add(new BookPage(bookModel, new RectF((w+pixelPadding) / 2, topPadding, (w-pixelPadding), (h-topPadding)), textPaint));
		}
		else {
			pages.add(new BookPage(bookModel, new RectF(pixelPadding, pixelPadding, (w-pixelPadding), (h-pixelPadding)), textPaint));
		}
	}

	@Override
	public void draw(Canvas canvas) {
		super.draw(canvas);
		for (BookPage page : pages) {
			page.draw(canvas);
		}
	}
	public void setBookModel(BookModel bookModel) {
		this.bookModel = bookModel;
		createPages(getWidth(), getHeight());
//		setStartPosition(bookModel.getStartPosition());
	}

	public BookPosition getStartPosition() {
		if(pages.isEmpty()) return bookModel.getStartPosition();
		return pages.getFirst().getStartPosition();
	}

	public void setStartPosition(BookPosition startPosition) {
		for (BookPage page : pages) {
			page.setStartPosition(startPosition);
			startPosition = page.getEndPosition();
		}
		invalidate();
	}

	public BookPosition getEndPosition() {
		if(pages.isEmpty()) return bookModel.getStartPosition();
		return pages.getLast().getEndPosition();
	}

	public void setEndPosition(BookPosition endPosition) {
		for (Iterator<BookPage> iterator = pages.descendingIterator(); iterator.hasNext(); ) {
			BookPage page = iterator.next();
			page.setEndPosition(endPosition);
			endPosition = page.getStartPosition();
		}
		setStartPosition(getStartPosition());
		invalidate();
	}
}
